package com.androidserver.server;

import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.androidserver.util.DatastoreWrapper;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.repackaged.org.json.JSONArray;
import com.google.appengine.repackaged.org.json.JSONException;
import com.google.appengine.repackaged.org.json.JSONObject;

@SuppressWarnings("serial")
public class Communicator extends HttpServlet {
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
	throws IOException {
		
		if (!req.getHeader("User-Agent").contains("Android")) {
			resp.getWriter().print("No browser access");
			return;
		}
		
		if (req.getParameter("action").equals("getAllGroups")) {
			sendAllGroups(req, resp);
		} else if (req.getParameter("action").equals("updateUser")) {
			sendUpdate(req, resp);
		} else if (req.getParameter("action").equals("getGroupMembers")) {
			sendGroupMembers(req, resp);
		} else if (req.getParameter("action").equals("getOwnerGroups")) {
			sendOwnerGroups(req, resp);
		} else if (req.getParameter("action").equals("update")) {
			sendUpdate(req, resp);
		} else if (req.getParameter("action").equals("validateMakeActive")) {
			sendValidateMember(req, resp);
		} else if (req.getParameter("action").equals("deleteMember")) {
			sendDeleteMember(req, resp);
		} else if (req.getParameter("action").equals("unjoin")) {
			sendUnjoinGroup(req, resp);
		}
		
		
	}
	
	private void sendOwnerGroups(HttpServletRequest req,
			HttpServletResponse resp) throws IOException {
		try {
			DatastoreWrapper dataWrapper = DatastoreWrapper.getInstance();
			List<Entity> groups = dataWrapper.getGroupsByOwner(req.getParameter("idCode"));
			JSONObject jsonOut = new JSONObject();
			JSONArray jsonGroups = new JSONArray();
			for (int i = 0; i < groups.size(); i++) {
				jsonGroups.put(groups.get(i).getProperty("groupName"));
			}
			jsonOut.put("groups", jsonGroups);
			resp.getWriter().print(jsonOut.toString());
		} catch (JSONException e) {
			resp.getWriter().print("{\"statusMessage\":\"error\"}");
		}
		
	}

	private void sendAllGroups(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		try {
			DatastoreWrapper dataWrapper = DatastoreWrapper.getInstance();
			List<Entity> groups = dataWrapper.getGroups();
			JSONObject jsonOut = new JSONObject();
			JSONArray jsonGroups = new JSONArray();
			for (int i = 0; i < groups.size(); i++) {
				jsonGroups.put(groups.get(i).getProperty("groupName"));
			}
			jsonOut.put("groups", jsonGroups);
			resp.getWriter().print(jsonOut.toString());
		} catch (JSONException e) {
			resp.getWriter().print("{\"statusMessage\":\"error\"}");
		}
	}
	
	private void sendUpdate(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		DatastoreWrapper dataWrapper = DatastoreWrapper.getInstance();
		boolean result = dataWrapper.updateMember(req.getParameter("idCode"),
				req.getParameter("latitude"), req.getParameter("longitude"));
		JSONObject jsonOut = getAllGroupsAndMembersAsJSON(req.getParameter("idCode"));
		if (jsonOut != null && result)
			resp.getWriter().print(jsonOut.toString());
		else 
			resp.getWriter().print("{\"statusMessage\":\"error\"}");
	}
	
	private JSONObject getAllGroupsAndMembersAsJSON(String idCode) {
		try {
			DatastoreWrapper dataWrapper = DatastoreWrapper.getInstance();
			JSONObject result = new JSONObject();
			List<Entity> groupsList = dataWrapper.getGroupsByMember(idCode);
			List<Entity> membersList;
			Entity temp;
			String members = "";
			JSONArray jsonGroups = new JSONArray();
			JSONArray jsonMembers = new JSONArray();
			for (int i = 0; i < groupsList.size(); i++) {
				jsonGroups.put(groupsList.get(i).getProperty("groupName"));
				membersList = dataWrapper.getGroupMembers(groupsList.get(i));
				for (int j = 0; j < membersList.size(); j++) {
					temp = membersList.get(j);
					members += temp.getProperty("memberName")
					+ "," + temp.getProperty("longitude")
					+ "," + temp.getProperty("latitude") + ";";
				}
				members = members.substring(0,members.length()-1);
				jsonMembers.put(members);
				members = "";
			}
			result.put("members", jsonMembers);
			result.put("groups", jsonGroups);
			result.put("statusMessage", "success");
			return result;
		} catch (JSONException e) {
			return null;
		}
	}

	private void sendGroupMembers(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		try {
			DatastoreWrapper dataWrapper = DatastoreWrapper.getInstance();
			String groupName = req.getParameter("groupName"); 
			Entity group = dataWrapper.getGroup(groupName);
			if (group != null) {
				List<Entity> members = dataWrapper.getGroupMembers(group);
				JSONObject jsonOut = new JSONObject();
				JSONArray jsonGroups = new JSONArray();
				for (int i = 0; i < members.size(); i++) {
					jsonGroups.put(members.get(i).getProperty("memberName"));
				}
				jsonOut.put("members", jsonGroups);
				resp.getWriter().print(jsonOut.toString());	
			} else {
				resp.getWriter().print("{\"statusMessage\":\"noSuchGroup\"}");
			}
		} catch (JSONException e) {
			resp.getWriter().print("{\"statusMessage\":\"error\"}");
		}
	}
	
	private void sendValidateMember(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		DatastoreWrapper dataWrapper = DatastoreWrapper.getInstance();
		String idCode = req.getParameter("idCode");
		String groupName = req.getParameter("groupName");
		Entity group = dataWrapper.getGroup(groupName);
		if (group.hasProperty(idCode)) resp.getWriter().print("OK");
		else resp.getWriter().print("FAIL");
	}
	
	private void sendDeleteMember(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		DatastoreWrapper dataWrapper = DatastoreWrapper.getInstance();
		boolean result = dataWrapper.removeMember(req.getParameter("idCode"));
		if (result) resp.getWriter().print("OK");
		else resp.getWriter().print("FAIL");
	}
	
	private void sendUnjoinGroup(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		DatastoreWrapper dataWrapper = DatastoreWrapper.getInstance();
		boolean result = dataWrapper.unjoinGroup(req.getParameter("idCode"), req.getParameter("groupName"));
		if (result) resp.getWriter().print("OK");
		else resp.getWriter().print("FAIL");
	}
}
